﻿using A.M.ETO;
using A.M.Storage.Application;
using A.M.Storage.I_Infrastruecure;
using AliInfor_Verification_code;
using AutoMapper;
using DotNetCore.CAP;
using L.M.System.Application.IServices;
using L.M.System.Domain.DTO;
using L.M.System.Domain.Entity;
using L.M.System.Infrastruecure.IRepository;
using Redis_ClientInfor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.ConstrainedExecution;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Yitter.IdGenerator;

namespace L.M.System.Application.Services
{
    /// <summary>
    /// 员工实体
    /// </summary>
    public class Staff_tableServices : BaseServices<staff_table, string>, IStaff_tableServices
    {
        private readonly IStaff_tableRepository staff_TableRepository;
        private readonly IOrganization_chartServices organization_ChartServices;
        private readonly IMapper mapper;
        private readonly ISystem_number_tableServices system_Number_TableServices;
        private readonly ICapPublisher capPublisher;
        private readonly IRole_authorit_listServices role_authorit_listServices;

        public Staff_tableServices(IStaff_tableRepository staff_TableRepository, IOrganization_chartServices organization_ChartServices, IMapper mapper, ISystem_number_tableServices system_Number_TableServices, ICapPublisher capPublisher, IRole_authorit_listServices role_authorit_listServices) : base(staff_TableRepository)
        {
            this.staff_TableRepository = staff_TableRepository;
            this.organization_ChartServices = organization_ChartServices;
            this.mapper = mapper;
            this.system_Number_TableServices = system_Number_TableServices;
            this.capPublisher = capPublisher;
            this.role_authorit_listServices = role_authorit_listServices;
        }

        /// <summary>
        /// 分页查询员工 + 分页
        /// </summary>
        /// <param name="pageSize">每页条数</param>
        /// <param name="pageIndex">当前页索引</param>
        /// <param name="tName">查询条件</param>
        /// <returns>分页查询员工 + 分页</returns>
        public async Task<ApiReturn<PageETO<StaffOrginDTO>>> Getstaff_tableShow(int pageSize, int pageIndex, string? tName)
        {
            ApiReturn<PageETO<StaffOrginDTO>> apiReturn = new ApiReturn<PageETO<StaffOrginDTO>>();
            PageETO<StaffOrginDTO> pageETO = new PageETO<StaffOrginDTO>();
            var slist = (await staff_TableRepository.GetShowQueryableAsync()).ToList();
            var olist = (await organization_ChartServices.GetShowQueryableAsync()).ToList();
            var list = (from a in slist
                        join b in olist
                        on a.department_number equals b.department_number
                        select new StaffOrginDTO
                        {
                            employee_number = a.employee_number,
                            employee_name = a.employee_name,
                            employee_job = a.employee_job,
                            employee_account = a.employee_account,
                            department_number = a.employee_number,
                            department_tel = a.department_tel,
                            department_remark = a.department_remark,
                            profile_picture = a.profile_picture,
                            department_name = b.department_name,
                        }).AsQueryable();
            if (!string.IsNullOrEmpty(tName))
            {
                list = list.Where(c => c.employee_name.Contains(tName)).AsQueryable();
            }
            pageETO.TotalCount = list.Count();
            pageETO.PageCount = Convert.ToInt32(list.Count() * 1.0 / pageSize);
            pageETO.Data = list.Skip(pageSize * (pageIndex - 1)).Take(pageSize).ToList();
            apiReturn.Code = 200;
            apiReturn.Message = "成功";
            apiReturn.ObjInfor = pageETO;
            return apiReturn;
        }

        /// <summary>
        /// 员工信息添加
        /// </summary>
        /// <param name="addDTO">实体</param>
        /// <returns>员工信息添加</returns>
        public async Task<ApiReturn<string>> SaffAddInfor(StaffAddDTO addDTO)
        {
            try
            {
                //开启事务
                system_Number_TableServices.BeginTranInfor();
                ApiReturn<string> apiReturn = new ApiReturn<string>();
                var saff = mapper.Map<staff_table>(addDTO);
                saff.employee_number = system_Number_TableServices.GetShowObj(c => c.system_name == "员工管理").system_number_serial;
                //给部门增一人
                var ores = await organization_ChartServices.GetShowObjAsync(c => c.department_number == addDTO.department_number);
                if (ores != null)
                {
                    ores.department_num += 1;
                }
                await organization_ChartServices.UpdInfor_Async(ores);
                var res = await staff_TableRepository.AddInfor_Async(saff);
                if (res > 0)
                {
                    apiReturn.Code = 200;
                    apiReturn.Message = "添加成功";
                    //添加成功需要传一个消息队列  传递哪个模块 还有编号
                    string numberName = "员工管理-" + saff.employee_number;
                    capPublisher.Publish("GetNewNumber", numberName);
                }
                else
                {
                    apiReturn.Code = 500;
                    apiReturn.Message = "添加失败";
                }
                system_Number_TableServices.CommitTranInfor();
                return apiReturn;
            }
            catch (Exception)
            {
                system_Number_TableServices.RollbackTranInfor();
                throw;
            }
        }

        /// <summary>
        /// 获取所有未关联角色的用户
        /// </summary>
        /// <returns>获取所有未关联角色的用户</returns>
        public async Task<List<StaffInforDTO>> GetShowAllInfor()
        {
            //所有的用户
            var list = await staff_TableRepository.GetShowInforAsync();
            //所有的关系表
            //var elist = await employee_Role_TableServices.GetShowInforAsync();

            // var usersWithoutRole = list.Where(u => !elist.Any(ur => ur.employee_number == u.employee_number)).ToList();


            var mlist = list.Select(c => new StaffInforDTO
            {
                key = c.employee_number,
                label = c.employee_name,
            }).ToList();
            return mlist;
        }

        /// <summary>
        /// 修改用户信息
        /// </summary>
        /// <param name="userInforDTO">修改用户信息</param>
        /// <returns>修改用户信息</returns>
        public async Task<ApiReturn<string>> UpdStainfor(UserInforDTO userInforDTO)
        {
            ApiReturn<string> apiReturn = new ApiReturn<string>();
            var res = await staff_TableRepository.GetShowObjAsync(c => c.employee_number == userInforDTO.staId);
            int a = 0;
            if (res != null)
            {
                res.profile_picture = userInforDTO.staImage;
                res.department_tel = userInforDTO.staTel;
                a = await staff_TableRepository.UpdInfor_Async(res);
            }
            if (a > 0)
            {
                apiReturn.Code = 200;
                apiReturn.Message = "修改成功";
            }
            else
            {
                apiReturn.Code = 500;
                apiReturn.Message = "修改失败";
            }
            return apiReturn;
        }


        /// <summary>
        /// 修稿密码
        /// </summary>
        /// <param name="passwordDTO">密码</param>
        /// <returns>修稿密码</returns>
        public async Task<ApiReturn<string>> UpdPassWord(PasswordDTO passwordDTO)
        {
            ApiReturn<string> apiReturn = new ApiReturn<string>();
            if (passwordDTO.IsPasswordNew != passwordDTO.PasswordNew)
            {
                apiReturn.Code = 400;
                apiReturn.Message = "新密码不一致";
                return apiReturn;
            }
            var res = await staff_TableRepository.GetShowObjAsync(c => c.employee_number == passwordDTO.StaId);
            if (res != null)
            {
                if (res.employee_cipher != passwordDTO.passwordinfor)
                {
                    apiReturn.Code = 400;
                    apiReturn.Message = "旧密码错误";
                    return apiReturn;
                }
                else
                {
                    res.employee_cipher = passwordDTO.IsPasswordNew;
                    await staff_TableRepository.UpdInfor_Async(res);
                    apiReturn.Code = 200;
                    apiReturn.Message = "修改成功";
                    return apiReturn;
                }
            }
            else
            {
                apiReturn.Code = 400;
                apiReturn.Message = "清先登录";
                return apiReturn;
            }
        }

        /// <summary>
        /// 修改用户信息
        /// </summary>
        /// <param name="staffUpdDTO">修改DTO</param>
        /// <returns>统一返回格式</returns>
        public async Task<ApiReturn<string>> StaffUpdInfor(StaffUpdDTO staffUpdDTO)
        {
            ApiReturn<string> apiReturn = new ApiReturn<string>();
            var res = await staff_TableRepository.GetShowObjAsync(c => c.employee_number == staffUpdDTO.employee_number);
            if (res != null)
            {
                res.employee_name = staffUpdDTO.employee_name;
                res.department_number = staffUpdDTO.department_number;
                res.department_tel = staffUpdDTO.department_tel;
                res.department_remark = staffUpdDTO.department_remark;
                var ges = await staff_TableRepository.UpdInfor_Async(res);
                if (ges > 0)
                {
                    apiReturn.Code = 200;
                    apiReturn.Message = "修改成功";
                }
                else
                {
                    apiReturn.Code = 400;
                    apiReturn.Message = "修改失败";
                }
            }
            else
            {
                apiReturn.Code = 500;
                apiReturn.Message = "清先选择修改的人员";
            }
            return apiReturn;
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="getUserInfor">User</param>
        /// <returns>统一返回格式</returns>
        public async Task<ApiReturn<SetUserInfor>> GetInforLogin(GetUserInfor getUserInfor)
        {
            try
            {
                //判断账号
                ApiReturn<SetUserInfor> apiReturn = new ApiReturn<SetUserInfor>();
                var user = await staff_TableRepository.GetShowObjAsync(c => c.employee_account == getUserInfor.employee_account);

                if (user == null)
                {
                    apiReturn.Code = 500;
                    apiReturn.Message = "该用户不存在,请重新输入";
                }
                else
                {
                    if (user.isDongInfor)
                    {
                        apiReturn.Code = 500;
                        apiReturn.Message = "该用户已经登录";
                    }
                    else
                    {
                        //判断是否为禁用状态
                        if (user.isdisabled)
                        {
                            apiReturn.Code = 500;
                            apiReturn.Message = "该账号已被禁用，请半小时后重试";
                        }
                        else
                        {
                            //判断密码是否正确
                            if (user.employee_cipher != getUserInfor.employee_cipher)
                            {
                                //密码错误要增加登录错误次数
                                user.number_of_logins += 1;
                                await staff_TableRepository.UpdInfor_Async(user);

                                if (user.number_of_logins == 3)
                                {
                                    //密码输入次数达到3次，更改用户状态，并赋值当前时间
                                    user.disableddate = DateTime.Now;
                                    user.isdisabled = true;
                                    await staff_TableRepository.UpdInfor_Async(user);
                                    apiReturn.Code = 500;
                                    apiReturn.Message = "该账号已被封禁，请半小时后重新登录";
                                }
                                else
                                {
                                    apiReturn.Code = 500;
                                    apiReturn.Message = "密码不正确，请重新输入，您还剩" + (3 - user.number_of_logins) + "次";
                                }
                            }
                            else
                            {
                                //登录成功，判断是否多次登录
                                if (user.number_of_logins != 0)
                                {
                                    user.number_of_logins = 0;
                                    user.disableddate = null;
                                }
                                user.isDongInfor = true;
                                await staff_TableRepository.UpdInfor_Async(user);
                                SetUserInfor setUserInfor = new SetUserInfor();
                                setUserInfor.employee_name = user.employee_name;
                                setUserInfor.employee_number = user.employee_number;
                                setUserInfor.employee_account = user.employee_account;
                                setUserInfor.employee_Image = user.profile_picture;
                                apiReturn.Code = 200;
                                apiReturn.ObjInfor = setUserInfor;
                                apiReturn.Message = "登录成功";
                            }

                        }
                    }
                }
                return apiReturn;
            }
            catch (Exception)
            {
                ApiReturn<SetUserInfor> apiReturn = new ApiReturn<SetUserInfor>();
                apiReturn.Code = 500;
                apiReturn.Message = "登录失败,请稍后重试";
                return apiReturn;
            }
        }

        /// <summary>
        /// 生成一个验证码
        /// </summary>
        /// <returns>生成一个验证码</returns>
        public ApiReturn<string> Verification_code()
        {
            ApiReturn<string> apiReturn = new ApiReturn<string>();
            //验证码标识编号
            var sId = YitIdHelper.NextId().ToString();
            var letter_cases = "abcdefghjkmnpqrstuvwxy";  //小写字母，去除可能干扰的i，l，o，z
            var upper_cases = letter_cases.ToUpper();  //大写字母
            var numert = "34567890";
            var init_chars = letter_cases + upper_cases + numert;
            var res = "";
            for (int i = 0; i < 4; i++)
            {
                Random random = new Random();

                // 生成一个介于 0 到 100 之间的随机整数
                int randomNumber = random.Next(0, init_chars.Length);
                res += init_chars[randomNumber];
            }
            //获取redis中的数据
            var getsecond = RedisClient.redisClient.GetStringKey(sId).ToString();
            if (getsecond == "")
            {
                apiReturn.Code = 200;
                apiReturn.Message = res + "_" + sId;
                //生成的验证码存入Redis中 2分钟
                RedisClient.redisClient.SetStringKey(sId, res, TimeSpan.FromMinutes(2));
            }
            else
            {
                apiReturn.Code = 500;
                apiReturn.Message = "请等待下次提交";
            }
            return apiReturn;
        }


        /// <summary>
        /// 密码验证码验证
        /// </summary>
        /// <param name="sId"></param>
        /// <param name="yId"></param>
        /// <returns></returns>
        public ApiReturn<string> GetVerification(string? sId,string? yId)
        {
            ApiReturn<string> apiReturn = new ApiReturn<string>();
            //先获取redis验证码
            var getsecond = RedisClient.redisClient.GetStringKey(sId).ToString();
            if (getsecond != "")
            {
                if (getsecond == yId)
                {
                    apiReturn.Code = 200;
                    apiReturn.Message = "";
                }
                else
                {
                    apiReturn.Code = 500;
                    apiReturn.Message = "验证失败";
                }
            }
            else
            {
                apiReturn.Code = 500;
                apiReturn.Message = "请重新刷新验证码";

            }
            return apiReturn;
        }




        /// <summary>
        /// 获取到手机号验证登录码
        /// </summary>
        /// <param name="uTel"></param>
        /// <returns></returns>
        public ApiReturn<SetUserInfor> GetTelLogin(string? uTel)
        {

            //传入的手机号进行验证
            ApiReturn<SetUserInfor> apiReturn = new ApiReturn<SetUserInfor>();

            //判断该账号未被注册
            var res = staff_TableRepository.GetShowObj(c => c.department_tel == uTel);
            if (res == null)
            {
                apiReturn.Code = 400;
                apiReturn.Message = "该账号未被注册";
            }
            else
            {
                //获取redis中的数据
                var getsecond = RedisClient.redisClient.GetStringKey(uTel).ToString();
                if (getsecond != "")
                {
                    apiReturn.Code = 500;
                    apiReturn.Message = "请稍后重试";
                }
                else
                {
                    //验证通过，生成验证码存入Redis中
                    var numert = "1234567890";
                    var ges = "";
                    for (int i = 0; i < 4; i++)
                    {
                        Random random = new Random();

                        // 生成一个介于 0 到 100 之间的随机整数
                        int randomNumber = random.Next(0, numert.Length);
                        ges += numert[randomNumber];
                    }
                    //通过API给手机发送短信
                    //测试发送短信验证码（阿里云）
                    bool isSuccess = AliInfor.SendMobileMessageByAli(uTel, "智能Mes生产管理系统", "SMS_465635094", ges);
                    if (isSuccess)
                    {
                        apiReturn.Code = 200;
                        apiReturn.Message = "成功";
                        //存入Redis中
                        RedisClient.redisClient.SetStringKey(uTel, ges, TimeSpan.FromMinutes(1));
                    }
                    else
                    {
                        apiReturn.Code = 200;
                        apiReturn.Message = "失败";
                    }
                }
            }

            return apiReturn;
        }


        /// <summary>
        /// 验证码登录
        /// </summary>
        /// <param name="uTel">手机号</param>
        /// <param name="code">验证码</param>
        /// <returns></returns>
        public async Task<ApiReturn<SetUserInfor>> TelInforLogin(string? uTel, string? code)
        {
            ApiReturn<SetUserInfor> apiReturn = new ApiReturn<SetUserInfor>();
            var res = await staff_TableRepository.GetShowObjAsync(c => c.department_tel == uTel);
            if (res.isDongInfor)
            {
                apiReturn.Code = 500;
                apiReturn.Message = "该账号以被登录";
            }
            else
            {
                if (res != null)
                {
                    //获取Redis
                    //获取redis中的数据
                    var getsecond = RedisClient.redisClient.GetStringKey(uTel).ToString();
                    if (getsecond == "")
                    {
                        apiReturn.Code = 500;
                        apiReturn.Message = "验证码失效，请重新点击";
                    }
                    else
                    {
                        if (getsecond != code)
                        {
                            apiReturn.Code = 500;
                            apiReturn.Message = "验证码错误，请重新输入";
                        }
                        else
                        {
                            res.isDongInfor = true;
                            await staff_TableRepository.UpdInfor_Async(res);
                            SetUserInfor setUserInfor = new SetUserInfor();
                            setUserInfor.employee_name = res.employee_name;
                            setUserInfor.employee_number = res.employee_number;
                            setUserInfor.employee_account = res.employee_account;
                            setUserInfor.employee_Image = res.profile_picture;
                            apiReturn.Code = 200;
                            apiReturn.Message = "登录成功";
                            apiReturn.ObjInfor = setUserInfor;
                        }
                    }
                }
                else
                {
                    apiReturn.Code = 500;
                    apiReturn.Message = "该账号未被祖册";
                }

            }

            return apiReturn;
        }

        /// <summary>
        /// 关闭浏览器去除状态
        /// </summary>
        /// <param name="uId"></param>
        /// <returns></returns>
        public async Task<ApiReturn<string>> GetUpdStaty(string? uId)
        {
            ApiReturn<string> apiReturn = new ApiReturn<string>();
            var res = await staff_TableRepository.GetShowObjAsync(c => c.employee_number == uId);
            if(res != null)
            {
                res.isDongInfor = false;
                await staff_TableRepository.UpdInfor_Async(res);
                apiReturn.Code = 200;
                apiReturn.Message = "OK";
            }
            else
            {
                apiReturn.Code = 500;
                apiReturn.Message = "OK";
            }
            return apiReturn;
        }
    }
}
